<?php

namespace control;
class inventoryClass extends adIndexClass
{
    private const page = 'inventory';
    private const table = 'inventory_take';
    private const tableMx = 'inventory_take_detail';
    private const tableRecord = 'inventory_record';
    private const title = '盘点单';
    private const state = ['草稿', '待确认', '已确认'];

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'orderNo'      => [
                        'name'  => '{l.inventory.homeSearch.orderNo}',
                        'width' => 300,
                        'sort' => 1,
                    ],
                    'warehouse' => [
                        'name'  => '{l.inventory.homeSearch.warehouse}',
                        'width' => 300,
                    ],
                    'surplus'  => [
                        'name'  => '{l.inventory.homeSearch.surplus}',
                        'width' => 200,
                    ],
                    'loss'         => [
                        'name'  => '{l.inventory.homeSearch.loss}',
                        'width' => 200,
                    ],
                    'orderDate'          => [
                        'name'  => '{l.inventory.homeSearch.orderDate}',
                        'width' => 300,
                        'sort' => 1,
                    ],
                    'state'        => [
                        'name'  => '{l.inventory.homeSearch.state}',
                        'width' => 200,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    L('inventory.home.orderNo') => text(array("name" => "orderNo")),
                    L('inventory.home.warehouse')   => selectMultiple([
                        'table' => 'warehouse',
                        'sqlField' => 'name',
                        'sqlId' => 'id',
                        "where" => " coid = '" . self::$coid . "' and state = '启用' " . self::getWarehouseSql(),
                        'name' => 'warehouseId',
                    ]),
                    L('inventory.homeSearch.orderDate') => text(['name' => 'orderDate', 'laydate' => ['range' => '~', 'type' => 'date'],]),
                ],
                [
                    L('inventory.home.state') => select(["name" => "state", 'option' => self::state]),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /**
     * 列表-查询条件
     *
     * @return string
     */
    public function home(): string
    {
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        $url = root . "control/adIndex.html?cla=" . self::page;
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"newIframe('" . L('inventory.homeSearch.detail') . "','" . $url . "&fun=edit')\" class='spanButton'>" . L('inventory.homeSearch.new') . "</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">" . L('inventory.homeSearch.del') . "</span>\n";
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /*客户列表-查询结果*/
    public function homeSearch(): string
    {
        //查询结果
        $where = " coid = '" . self::$coid . "' " . self::getWarehouseSql('warehouseId');
        $equal = [
            'orderNo'     => $this->post('orderNo'),
            'warehouseId' => $this->post('warehouseId'),
        ];
        $like  = [
            'type'  => $this->post('type'),
            'state' => $this->post('state'),
        ];
        //生成查询语句
        $where .= search([
            "="    => $equal,
            "like" => $like,
        ]);
        if ($this->post('orderDate')) {
            $where .= self::timeComparison($this->post('orderDate'), 'date', 'orderDate');
        }
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        $page = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //获取记录
        $url = root . "control/adIndex.html?cla=" . self::page;
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate     = array(
                "box"    => array("name" => "listId", "value" => $array['id']),
                "detail" => array(
                    "title" => L('inventory.homeSearch.detail'),
                    "click" => "newIframe('" . L('inventory.homeSearch.detail') . "','" . $url . "&fun=detail&id=" . $array['id'] . "')",
                ),
                "edit"   => $array['state'] == '草稿' ? [
                    "title" => L('inventory.homeSearch.edit'),
                    "click" => "newIframe('" . L('inventory.homeSearch.detail') . "','" . $url . "&fun=edit&id=" . $array['id'] . "')",
                ] : [],
            );
            $loss = self::lostZero(find([
                'table'  => self::tableMx,
                'single' => "orderId = '{$array['id']}' and orderNum > num",
                'field'  => "ifnull(sum(orderNum-num),0) as num",
            ])['num'],'numPrecision');
            $surplus = self::lostZero(find([
                'table'  => self::tableMx,
                'single' => "orderId = '{$array['id']}' and orderNum < num",
                'field'  => "ifnull(sum(num-orderNum),0) as num",
            ])['num'],'numPrecision');
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case "surplus":
                        $row[] = $surplus;
                        break;
                    case "loss":
                        $row[] = $loss;
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        $total = find([
            'table'  => self::tableMx,
            'single' => "orderId in (select id from ".self::table." where {$where})",
            'field'  => "sum(if(num<orderNum,orderNum-num,0))numK,sum(if(num<orderNum,0,num-orderNum))numY ",
        ]);
        $total    = [
            'surplus'        => self::lostZero($total['numY'], 'numPrecision'),
            'loss'   => self::lostZero($total['numK'], 'numPrecision'),
        ];
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
            "total"       => $total,
        ));
        //返回
        $json['html'] = "<form name='listForm'>" . $li . "</form>" . $page['button'] . clear;
        return json_encode($json, 320);
    }
    /**
     * 保存并提交
     * @return bool|string
     */
    public function saveAndCommit(): bool|string
    {
        $resultJson = $this->editEdit();
        $result = json_decode($resultJson,true);
        if ($result['warn'] == 2){
            unset($_SESSION['warn']);
            $resultJson = $this->commitEdit();
        }
        return $resultJson;
    }

    public function arrayDeal($mold, $array): array
    {
        switch ($mold) {
            case 1:
                unset($array[5], $array[6]);
                break;
            case 2:
                unset($array[6]);
                break;
        }
        return array_values($array);
    }

    public function arrayDealDetail($mold, $array): array
    {
        switch ($mold) {
            case 1:
                unset($array[4], $array[5]);
                break;
            case 2:
                unset($array[5]);
                break;
        }
        return array_values($array);
    }

    /**
     * 编辑页
     *
     * @return string
     */
    public function edit(): string
    {
        $id       = $this->get('id');
        $info     = query(self::table, " coid = '" . self::$coid . "' AND id = '" . $id . "' ");
        $button[] = [
            'style' => 'li-btn-blue-bg',
            "name"  => L('inventory.edit.save'),
            "type"  => "点击事件",
            "title" => L('inventory.edit.save'),
            'fun'   => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=editEdit')",
        ];
        $button[] = [
            "name" => "保存并提交",
            "type" => "点击事件",
            "title" => "保存",
            'fun' => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=saveAndCommit')"
        ];
        $mold     = $info['mold'] ?: 1;
        $tr[]     = $this->arrayDeal($mold, ['', '{l.inventory.edit.code}', '{l.inventory.edit.name}', '{l.inventory.edit.model}', '{l.inventory.edit.unit}', '库位', '批号', '{l.inventory.edit.inventoryNum}', '{l.inventory.edit.num}', '起始液位', '截止位置']);
        $result   = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by time"));
        $totalArr = ['inventoryNum'=>0,'num'=>0];
        foreach ((array)$result['array'] as $k=>$array) {
            $material     = query('material', " id = '$array[materialId]'");
            $positionId   = $mold == 2 || $mold == 3 ? $array['positionId'] : false;
            $batch        = $mold == 3 ? $array['batch'] : false;
            $inventoryNum = inventoryBalanceClass::inventoryNum($material['id'], $info['warehouseId'], $positionId, $batch);
            $position     = query('warehouse_position', " id = '$array[positionId]'", "name");
            $tr[]         =
                $this->arrayDeal($mold, [
                    componentClass::tablePperation($k+1).
                    hidden(['name' => 'mxId[]', 'value' => $array['id']]) .
                    hidden(['name' => 'materialId[]', 'value' => $array['materialId'],]) .
                    hidden(array('name' => 'positionId[]', 'value' => $array['positionId'])) .
                    hidden(array('name' => 'batch[]', 'value' => $array['batch'])) .
                    hidden(['name' => 'unit[]', 'value' => $array['unit'],]),
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $array['unit'],
                    $position['name'],
                    $array['batch'],
                    "<span class='inventoryNum'>".self::lostZero($inventoryNum, 'numPrecision')."</span>",
                    text([
                        'name' => 'num[]',
                        'blur' => "textUpdate",
                        'value' => self::lostZero($array['num'], 'numPrecision'),
                        'other' => self::digitalFiltering('numPrecision')
                    ]),
                    text([
                        'name' => 'start_position[]',
                        'value' => self::lostZero($array['start_position'], 'numPrecision'),
                        'other' => self::digitalFiltering('numPrecision')
                    ]),
                    text([
                        'name' => 'end_position[]',
                        'value' => self::lostZero($array['end_position'], 'numPrecision'),
                        'other' => self::digitalFiltering('numPrecision')
                    ]),
                ]);
            $totalArr['inventoryNum'] += $inventoryNum;
            $totalArr['num'] += $array['num'];
        }
        $total = $this->arrayDeal($mold, [
            "",
            "",
            "",
            "",
            "",
            "",
            "",
            "<span id='total_inventory'>".self::lostZero($totalArr['inventoryNum'],'numPrecision')."</span>",
            "<span id='total_num'>".self::lostZero($totalArr['num'],'numPrecision')."</span>",
        ]);
        $list = $this->listTable(array('tr' => $tr, 'end' => true, 'total' => $total));

        $getBookInventoryWord = L('inventory.edit.getBookInventory');
        $but                = <<<EOT
		    <span class="smallButton" onclick="getBookInventory(1)">按仓库获取账面库存</span>
		    <span class="smallButton" onclick="getBookInventory(2)">按库位获取账面库存</span>
		    <span class="smallButton" onclick="getBookInventory(3)">按批号获取账面库存</span>
		EOT;

        //表单
        $data['button'] = $this->tableShowButton($button);
        $body = $this->edit4([
            '基本信息' => [
                [
                    must . L('inventory.edit.warehouse') => selectMultiple([
                            'table' => 'warehouse',
                            "title" => L('inventory.edit.warehouse'),
                            'sqlField' => 'name',
                            'sqlId' => 'id',
                            'name' => 'warehouseId',
                            'value' => $info['warehouseId'],
                            "where" => " coid = '" . self::$coid . "' and state = '启用' " . self::getWarehouseSql() .' order by time asc',
                            'change' => 'assign'
                        ]) . hidden(['name' => 'warehouse', 'value' => $info['warehouse'],]),
                    L('inventory.edit.type')  => materialClass::typeSelect($info['type'],name: 'type'),
                ],
                [
                    L('inventory.edit.text') => textarea(['name' => "text", 'class' => 'text', 'value' => $info['text']]),
                ],
            ]
        ]);
        $body .= $this->editList([
            'id' => 'materialTable',
            'title' => L('inventory.edit.choiceMx'),
            'button' => $but,
            'html' => $list,
        ]);
        $data['html'] = $this->pageEdit([
            "html"  => $body,
            'hidden' => hidden(['name' => 'id', 'value' => $id]).hidden(['name' => 'mold', 'value' => $mold]),
        ]);
        $data['html'] .= <<<EOT
			<script>
			//获取账面库存
			function getBookInventory(mold){
			    $("[name='mold']").val(mold)
			    $("#materialTable").find('table').remove()
				$.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addBookInventory', $('form[name=inventoryEditForm]').serialize(), function(res) {
			        if(res.warn !== 2){
			            msg(res.warn, 'error')
			        }else{
                        $("#materialTable").append(res.html);
                        calculateTotal()
			        }
			    }, 'json')
			}
			// 单个文本框更新
            function textUpdate(obj) {
                $(obj).css('background-color','#fdc1c1')
                calculateTotal()
            }
            //计算总数量
            function calculateTotal(){
                let table = $('.editList')
                let num = 0,
                inventoryNum = 0
                table.find("[name='num[]']").each(function(index){
                    if($(this).val()){
                      num+=Number($(this).val());
                    }
                    var inventoryNumText = table.find(".inventoryNum").eq(index).text()
                    if(inventoryNumText){
                        inventoryNum+=Number(inventoryNumText);
                    }
                })
                $("#total_num").text(num.toFixed(publicSettings.numPrecision.num));
                $("#total_inventory").text(inventoryNum.toFixed(publicSettings.numPrecision.num));
            }
			</script>
EOT;
        //返回
        return $this->tab($data);
    }

    /**
     * 编辑
     *
     * @return bool|string
     */
    public function addBookInventory(): string
    {
        $mold       = $this->post('mold')?:1;
        $field      = [
            'warehouseId' => $this->post('warehouseId'),
            'type'      => $this->post('type'),
        ];
        $annotation = [
            'warehouseId' => L('inventory.addBookInventory.warehouseId'),
            'type'      => L('inventory.addBookInventory.typeId'),
        ];
        $rules      = [
            'warehouseId' => 'required',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0]; // 多个规则提示最前面一条
            goto resp;
        } elseif (!$this->power(self::page, 'edit')) {
            $json['warn'] = L('inventory.addBookInventory.power');
        } else {
            $and   = search([
                'like'   => [
                    'typePath' => $this->post('type'),
                ],
            ]);
            $where = "coid = '" . self::$coid . "' AND " . generateWhere(['warehouseId' => $field['warehouseId']]);
            if ($and) {
                $where .= " and materialId IN (SELECT id FROM `material` WHERE 1=1 $and ) ";
            }
            switch ($mold) {
                case 2:
                    $fieldArr = self::resolveField([
                        'field' => '`materialId`, `positionId`, SUM(num) as num',
                        'group' => 'materialId,positionId',
                    ]);
                    break;
                case 3:
                    $fieldArr = self::resolveField([
                        'field' => '`materialId`, `positionId`, `batch`, SUM(num) as num',
                        'group' => 'materialId,positionId,batch',
                    ]);
                    break;
                default:
                    $fieldArr = self::resolveField([
                        'field' => '`materialId`, SUM(num) as num',
                        'group' => 'materialId',
                    ]);
            }
            $result = find([
//                'field' => $fieldArr['field'],
                'table' => self::tableRecord,
                'where' => $where . $fieldArr['group'] . ' order by materialId desc',
            ]);
            if (!$result['array']) {
                $json['warn'] = '无匹配数据';
            } else {
                $tr[]     = $this->arrayDeal($mold, ['', '{l.inventory.edit.code}', '{l.inventory.edit.name}', '{l.inventory.edit.model}', '{l.inventory.edit.unit}', '库位', '批号', '{l.inventory.edit.inventoryNum}', '{l.inventory.edit.num}', '起始液位', '截止位置']);
                $totalArr = ['inventoryNum'=>0,'num'=>0];
                foreach ($result['array'] as $k=>$array) {
                    $mxId        = $array['materialId'];
                    $material       = query('material', "id = '$mxId'");
                    if (empty($material['id'])) {
                        continue;
                    }
                    $positionId = $array['positionId'] ?? '';
                    $position   = $positionId ?
                        query('warehouse_position', " id = '" . $positionId . "' ", "name")['name'] :
                        '';
                    $bacth      = $array['batch'] ?? '';
                    $id             = self::getId();
                    $tr[]         =
                        $this->arrayDeal($mold, [
                            componentClass::tablePperation($k+1).
                            hidden(['name' => 'mxId[]', 'value' => $id]) .
                            hidden(['name' => 'materialId[]', 'value' => $mxId]) .
                            hidden(array('name' => 'positionId[]', 'value' => $positionId)) .
                            hidden(array('name' => 'batch[]', 'value' => $bacth)) .
                            hidden(['name' => 'unit[]', 'value' => $material['unit']]),
                            $material['code'],
                            $material['name'],
                            $material['model'],
                            $material['unit'],
                            $position,
                            $bacth,
                            "<span class='inventoryNum'>".self::lostZero($array['num'], 'numPrecision')."</span>",
                            text([
                                'name' => 'num[]',
                                'blur' => "textUpdate",
                                'value' => self::lostZero($array['num'], 'numPrecision'),
                                'other' => self::digitalFiltering('numPrecision')
                            ]),
                            text([
                                'name' => 'start_position[]',
                                'value' =>$array['start_position'] ? self::lostZero($array['start_position'], 'numPrecision') : 0,
                                'other' => self::digitalFiltering('numPrecision')
                            ]),
                            text([
                                'name' => 'end_position[]',
                                'value' => $array['end_position'] ? self::lostZero($array['end_position'], 'numPrecision'): 0,
                                'other' => self::digitalFiltering('numPrecision')
                            ]),
                        ]);
                    $totalArr['inventoryNum'] += $array['num'];
                    $totalArr['num'] += $array['num'];
                }
                $total = $this->arrayDeal($mold, [
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "<span id='total_inventory'>".self::lostZero($totalArr['inventoryNum'],'numPrecision')."</span>",
                    "<span id='total_num'>".self::lostZero($totalArr['num'],'numPrecision')."</span>",
                ]);
                $json['html'] = $this->listTable(array('tr' => $tr, 'end' => true, 'total' => $total));
                $json['warn'] = 2;
            }
        }

        resp:
        return json_encode($json, 320);
    }

    public function editEdit(): string
    {
        $id               = $this->post('id') ?: self::getId();
        $mxIdArr          = $this->post('mxId') ?: [];
        $materialIdArr = $this->post('materialId');
        $positionIdArr    = $this->post('positionId');
        $batchArr         = $this->post('batch');
        $numArr           = $this->post('num');
        $start_positionArr           = $this->post('start_position');
        $end_positionArr           = $this->post('end_position');
        $unitArr          = $this->post('unit');
        $field            = [
            'warehouseId' => $this->post('warehouseId'),
            'warehouse'   => $this->post('warehouse'),
            'type'        => $this->post('type'),
            'text'        => $this->post('text'),
            'mold'        => $this->post('mold'),
        ];
        $annotation       = [
            'warehouseId' => L('inventory.editEdit.warehouseId'),
            'warehouse'   => L('inventory.editEdit.warehouse'),
            'type'        => L('inventory.editEdit.type'),
            'text'        => L('inventory.editEdit.text'),
        ];
        $rules            = [
            'warehouseId' => 'required',
            'warehouse'   => 'required',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0]; // 多个规则提示最前面一条
            goto resp;
        }
        $where = " coid = '" . self::$coid . "' AND id = '$id' ";
        $info  = query(self::table, $where);
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = L('inventory.editEdit.power');
        } elseif (static::is_null_array($mxIdArr)) {
            $json['warn'] = L('inventory.editEdit.choiceMx');
        } elseif (static::is_null_array($materialIdArr)) {
            $json['warn'] = L('inventory.editEdit.choiceMx');
        } elseif (static::is_null_array($numArr)) {
            $json['warn'] = '数量请填写完整';
        } else {
            if (!empty($info['id']) && $info['state'] == '已确认') {
                $json['warn'] = L('inventory.editEdit.stateError');
            } else {
                $this->startTrans();
                $isPass = true;//事务通过标志
                if (!$info['id']) {
                    $orderNo      = codeTemplateClass::generateCode(self::page, [
                        'prefix' => 'PD' . date('Ymd'),
                        'table'  => self::table,
                        'field'  => 'orderNo',
                        'where'  => " AND coid = '" . self::$coid . "' ",
                    ], $field);
                    $field        = array_merge($field, [
                        'id'        => $id,
                        'orderDate' => $this->date,
                        'orderNo'   => $orderNo,
                        'state'     => '草稿',
                        'coid'      => self::$coid,
                        'stid'      => $this->control['stid'],
                    ]);
                    $json['warn'] = static::insert(["table" => self::table, "field" => $field]);
                } else {
                    $json['warn'] = static::update([
                        "table" => self::table,
                        "field" => $field,
                        "where" => $where,
                    ]);
                }
                //添加或更新盘点单明细
                if (is_array($mxIdArr)) {
                    foreach ($mxIdArr as $k => $nid) {
                        $mx           = query(self::tableMx, "id = '$nid'");
                        $start_positionArrId = $start_positionArr[$k] ?: 0;
                        $end_positionArrId = $end_positionArr[$k] ?: 0;
                        if(in_array($field['warehouseId'],['a24a5ef66ecbf393','a71bcc8505ead797','a9524696ab7d36e7'])){
                            //液氨计算重量
                            $liquid_ammonia = query('liquid_ammonia',"type = 1 and liquid_level = '$start_positionArrId'");
                            $liquid_ammoniaEnd = query('liquid_ammonia',"type = 1 and liquid_level = '$end_positionArrId'");
                            $num_data = $liquid_ammoniaEnd['weight'] - $liquid_ammonia['weight'];
                        }else{
                            $liquid_ammonia = query('liquid_ammonia',"type = 2 and liquid_level = '$start_positionArrId'");
                            $liquid_ammoniaEnd = query('liquid_ammonia',"type = 2 and liquid_level = '$end_positionArrId'");
                            $num_data = $liquid_ammoniaEnd['weight'] - $liquid_ammonia['weight'];
                        }
                        $numArr[$k]   = self::formattingFigure($numArr[$k], 'numPrecision');
                        $positionId   = $field['mold'] == 2 || $field['mold'] == 3 ? $positionIdArr[$k] : false;
                        $batch        = $field['mold'] == 3 ? $batchArr[$k] : false;
                        $inventoryNum = inventoryBalanceClass::inventoryNum($materialIdArr[$k], $field['warehouseId'], $positionId, $batch);
                        $num_data = $inventoryNum + $num_data;

                        if (!empty($mx['id'])) {
                            //更新
                            $warn = static::update([
                                "table" => self::tableMx,
                                "field" => [
                                    'coid'          => self::$coid,
                                    'materialId'    => $materialIdArr[$k],
                                    'warehouseId'   => $field['warehouseId'],
                                    'positionId'    => $positionIdArr[$k],
                                    'batch'         => $batchArr[$k],
                                    'orderNum'      => $inventoryNum,
                                    'num'           => $num_data ,
                                    'start_position'           => $start_positionArrId,
                                    'end_position'           => $end_positionArrId,
                                    'unit'          => $unitArr[$k],
                                ],
                                "where" => " id = '$nid'",
                            ]);
                        } else {
                            //新增
                            $warn = static::insert([
                                "table" => self::tableMx,
                                "field" => [
                                    'id'            => $nid,
                                    'coid'          => self::$coid,
                                    'orderId'       => $id,
                                    'materialId'    => $materialIdArr[$k],
                                    'warehouseId'   => $field['warehouseId'],
                                    'positionId'    => $positionIdArr[$k],
                                    'batch'         => $batchArr[$k],
                                    'orderNum'      => $inventoryNum,
                                    'num'           => $num_data ,
                                    'start_position'           => $start_positionArrId,
                                    'end_position'           => $end_positionArrId,
                                    'unit'          => $unitArr[$k],
                                ],
                            ]);
                        }
                        if (!in_array($warn, ['新增成功', '更新成功'])) {
                            $isPass       = false;
                            $json['warn'] = $warn;
                            break;
                        }
                    }
                }
                if (in_array($json['warn'], ["新增成功", "更新成功"]) && $isPass) {
                    $this->commitTrans();
                    delete(
                        [
                            'table' => self::tableMx,
                            'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'",
                        ]
                    );
                    //添加日志
                    $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                    $text = str_replace(['{{staffName}}', '{{type}}', '{{id}}'], [$this->control['name'], $type, $id], L('inventory.editEdit.log'));
                    $this->logText(["type" => self::page, "text" => $text]);
                    //返回
                    $_SESSION['warn'] = $json['warn'];
                    $json['warn']     = 2;
                    $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $id;
                } else {
                    $this->rollback();
                }
            }
        }

        resp:
        return json_encode($json, 320);
    }


    /*详情页*/
    public function detail(): string
    {
        $info = query(self::table, " coid = '" . self::$coid . "' AND id = '{$this->get('id')}'");
        if (empty($info['id'])) {
            $html = L('inventory.detail.empty');
        } else {
            //菜单
            $data   = [
                "id" => $info['id'],
            ];
            $button = [];
            if ($this->power(self::page, "edit") && $info['state'] != '已确认') {
                if ($info['state'] == '草稿') {
                    //按钮
                    $button[] = [
                        "name"  => L('inventory.detail.edit'),
                        "type"  => "顶部页卡",
                        "title" => L('inventory.detail.editInventory'),
                        "url"   => $this->root . "control/adIndex.html?cla={$this->get('cla')}&fun=edit&id=" . $info['id'],
                        'style' => 'li-btn-blue-bg',
                    ];
                    //按钮
                    $button[] = [
                        "name" => L('inventory.detail.sub'),
                        "type" => "弹出层",
                        "cla"  => $this->get('cla'),
                        "fun"  => "operate",
                        "post" => ["act" => 'commit', "id" => $info['id']],
                    ];
                }
                //按钮
                $button[] = [
                    "name" => L('inventory.detail.del'),
                    "type" => "弹出层",
                    "cla"  => $this->get('cla'),
                    "fun"  => "operate",
                    "post" => ["act" => 'del', "id" => $info['id']],
                ];
            }
            if ($this->power(self::page, "confirm") && $info['state'] == '待确认') {
                $button[] = [
                    "name"  => L('inventory.detail.confirm'),
                    "type"  => "弹出层",
                    "cla"   => $this->get('cla'),
                    "fun"   => "operate",
                    "post"  => ["act" => 'confirm', "id" => $info['id']],
                    'style' => 'li-btn-blue-bg',
                ];
            }
            if ($this->power(self::page, "confirm") && $info['state'] != '草稿') {
                $button[] = [
                    "name" => L('inventory.detail.cancel'),
                    "type" => "弹出层",
                    "cla"  => $this->get('cla'),
                    "fun"  => "operate",
                    "post" => ["act" => 'cancel', "id" => $info['id']],
                ];
            }
            //操作记录
            $button[] = self::operateLogBut($info['id']);

            $mxtr[] = $this->arrayDealDetail($info['mold'], ['{l.inventory.detail.code}', '{l.inventory.detail.name}', '{l.inventory.detail.model}', '{l.inventory.detail.unit}', '库位', '批号', '{l.inventory.detail.orderNum}', '{l.inventory.detail.num}', '{l.inventory.detail.difference}', '起始液位', '截止位置']);
            $totalArr = ['orderNum'=>0,'num'=>0];
            $result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by time"));
            foreach ($result['array'] as $array) {
                $material    = query('material', " id = '$array[materialId]'");
                $position    = query('warehouse_position', " id = '$array[positionId]'", "name");
                $mxtr[]      = $this->arrayDealDetail($info['mold'], [$material['code'], $material['name'], $material['model'], $material['unit'], $position['name'], $array['batch'], self::lostZero($array['orderNum'], 'numPrecision'), self::lostZero($array['num'], 'numPrecision'), self::formattingFigure($array['num'] - $array['orderNum'], 'numPrecision'),self::lostZero($array['start_position'], 'numPrecision'), self::lostZero($array['end_position'], 'numPrecision'), ]);
                $totalArr['orderNum'] += $array['orderNum'];
                $totalArr['num'] += $array['num'];
            }
            $total_tr = $this->arrayDealDetail($info['mold'], [
                "",
                "",
                "",
                "",
                "",
                "",
                $totalArr['orderNum']?self::lostZero($totalArr['orderNum'],'numPrecision'): 0,
                $totalArr['num']?self::lostZero($totalArr['num'],'numPrecision'): 0,
                "",
                "",
                "",
            ]);
            $mxButton = '';
//            if ($info['state'] != '已确认' && $this->power(self::page, "export")) {
//                $mxButton .="<span class='smallButton' onclick=\"layer('importTemplate','exportFrame',{cla:'".self::page."',id:'{$info['id']}',exportFun:'exportDetail'})\">导出</span>";
//            }
            if ($info['state'] != '已确认' && $this->power(self::page, 'import')) {
                $mxButton .="<span class='smallButton' onclick=\"layer('importTemplate','importFrame',{cla:'".self::page."',orderId:'{$info['id']}'})\">导入</span>";
            }
            if ($this->power(self::page, "export")) {
                $mxButton .="<span class='smallButton' onclick=\"layer('importTemplate','exportFrame',{cla:'".self::page."',orderId:'{$info['id']}'})\">导出</span>";
            }
            if ($info['state'] == '已确认') {
//                $mxButton    .= "<a href='" . root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=exportData&id=" . $info['id'] . "' class='spanButton mar10'>" . L('inventory.detail.export') . "</a>\n";
                $surplusWord = L('inventory.detail.surplus');
                $lossWord    = L('inventory.detail.loss');
                $mxButton    .= <<<EOT
				 
					<span class="smallButton" onclick="generateInventory('{$info['id']}', '盘盈单')">$surplusWord</span>
					<span class="smallButton" onclick="generateInventory('{$info['id']}', '盘亏单')">$lossWord</span>
				EOT;
            }

            //生成表单
            $data['button'] = $this->tableShowButton($button);
            $data['html'] = $this->tableShow([
                '详细信息' => [
                    [
                        L('inventory.detail.warehouse')    => $info['warehouse'],
                        L('inventory.detail.materialType') => materialClass::getTypePath($info['type']),
                        L('inventory.detail.orderNo') => $info['orderNo'],
                        L('inventory.detail.stid')    => self::findStaff($info['stid']),

                    ],
                    [
                        L('inventory.detail.state')   => $info['state']
                    ],
                    [
                        L('inventory.detail.text') => pre($info['text']),
                    ],
                ],
            ]);
            $data['html'] .= $this->detailList([
                'title' => L('inventory.detail.inventoryMx'),
                'button' => $mxButton,
                'html' => $this->listTable(array('tr' => $mxtr, 'showEmpty' => true, 'showSort' => true, 'total' => $total_tr)),
            ]);
            //生成页面
            $html = $this->tab($data);
            // JS
            $html .= <<<EOT
			<script>
			//获取账面库存
			function getBookInventory(){
				$.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addBookInventory', $('form[name=inventoryEditForm]').serialize(), function(res) {
			        if(res.warn !== 2){
			            msg(res.warn, 'error')
			        }else{
                        $("#materialTable tr").not('tr:eq(0)').remove()
                        $("#materialTable tr:eq(0)").after(res.html);
			        }
			    }, 'json')
			}
            //生成盈亏单
            function generateInventory(id, type){
            	$.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=generateInventory', {'id': id, 'type': type}, function(res) {
			        if(res.warn === 2){
                        if (res.href) {
			                window.location.href = res.href;
			            } else {
			                window.location.reload();
			            }
			        }else{
				        msg(res.warn, 'error')
			        }
			    }, 'json')
            }
			</script>
EOT;
        }
        //返回
        return $html;
    }

    /**
     * 导出明细
     */
    public function exportDetail()
    {
        if (!$this->power(self::page, 'export')) {
            $_SESSION['warn'] = L('inventory.exportDetail.power');
        } else {
            $info = query(self::table, " id = '{$this->get('id')}' ");
            if (empty($info['id'])) {
                $_SESSION['warn'] = L('inventory.exportDetail.none');
            } else {
                $data   = [];
                $title  = [L('inventory.detail.code'), L('inventory.detail.name'), L('inventory.detail.model'), L('inventory.detail.unit'), L('inventory.detail.orderNum'), L('inventory.detail.num')];
                $result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by time"));
                foreach ($result['array'] as $array) {
                    $material    = query('material', " id = '$array[materialId]'");
                    $data[]      = [$material['code'], $material['name'], $material['model'], $material['unit'], self::lostZero($array['orderNum'], 'numPrecision'), ''];
                }
                $text = str_replace(['{{staffName}}'], [$this->control['name']], L('inventory.exportDetail.log'));
                $this->logText(["type" => self::page, "text" => $text]);
                $this->excelOut($title, $data, L('inventory.exportDetail.fileName') . ".xlsx");
                exit(0);
            }
        }

        header("Location:" . getenv("HTTP_REFERER"));

    }

    /**
     * 下载模板
     */
    public function downloadModel()
    {
        $orderId = $this->get('orderId');
        $info    = query(self::table, " coid = '" . self::$coid . "' AND id = '{$orderId}'");
        $templateId = $this->get('templateId');
        if (!$this->power(self::page, 'import')) {
            $_SESSION['warn'] = L('inventory.downloadModel.power');
        } else {
            $exampleData = [];
            $excel    = $this->excelHead();
            $fileName = self::title.'导入模板-'.importTemplateClass::getName($templateId).'.xlsx';
            $filePath = $excel->fileName($fileName, 'sheet1');
            $format = new \Vtiful\Kernel\Format($filePath->getHandle());
            $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
            $index         = 0;
            foreach ($templateField as $k => $array) {
                if ($array['display']){
                    if($info['mold'] == 1 && ($array['columnName'] == '库位' || $array['columnName'] == '批号')){
                        continue;
                    }elseif($info['mold'] == 2 && $array['columnName'] == '批号'){

                        continue;
                    }
                    $backgroundStyle=null;
                    if (importTemplateClass::getIsMustValue($this->importFieldInit(), $array['columnName'])){
                        //必填项判断
                        $backgroundStyle  = $format->background(
                            0xFFC04B
                        )->toResource();
                    }
                    $filePath->insertText(0, $index, $array['aliasName'],'',$backgroundStyle);
                    foreach ($exampleData as $y=>$example){
                        $exampleVal = match ($array['columnName']){
                            '物料编码'=>$example[0],
                            '物料名称'=>$example[1],
                            '规格型号'=>$example[2],
                            '单位'=>$example[3],
                            '库位'=>$example[4],
                            '批号'=>$example[5],
                            '系统库存'=>$example[6],
                            '盘点库存'=>$example[7],
                            default=>'',
                        };
                        $filePath->insertText($y+1, $index, $exampleVal);
                    }
                    $index++;
                }
            }
            $text   = str_replace(['{{staffName}}'], [$this->control['name']], L('inventory.downloadModel.log'));
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOutPut($filePath,$fileName);
            exit(0);
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }

    /**
     * Excel导入
     */
    public function importData()
    {
        $orderId = $this->post('orderId');
        $info    = query(self::table, " coid = '" . self::$coid . "' AND id = '{$orderId}'");
        $templateId = $this->post('templateId');
        if (!$this->power(self::page, 'import')) {
            $json['warn'] = L('inventory.importData.power');
        } else {
             $fomatArray = [];//导入数据格式同一为TYPE_STRING
            foreach ($this->importFieldInit() as $value){
                $fomatArray[] = \Vtiful\Kernel\Excel::TYPE_STRING;
            }
            $data = $this->importHead(format: $fomatArray);
            $x    = 0;
            $text = '';
            $headArray = [];
            $row_list=0;
            foreach ($data as $i => $row) {
                $row_list++;
                if ($i==0){
                    $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
                    $headArray = importTemplateClass::combinHead($templateField,$row);
                }
                if ($i > 0) {
                    $rowData = formSubArray($row);
                    //只接收模板中选中的字段的值
                    $cell = [];
                    foreach ($headArray as $index=>$headName){
                        $cell[$headName] = $rowData[$index]??'';
                    }
                    //初始化未被模板需要的字段的值
                    foreach ($this->importFieldInit() as $value){
                        $cell[$value['columnName']] = $cell[$value['columnName']]??'';
                    }

                    $material = query('material', " coid = '" . self::$coid . "' AND code = '$cell[物料编码]' ");
                    if (!$material['id']) {
                        $text .= str_replace(['{{i}}'], [$row_list], L('inventory.importData.empty')) . "<br>";
                    } else {
                        switch ($info['mold']) {
                            case 2:
                                $position = query('warehouse_position', " orderId = '$info[warehouseId]' and name = '$cell[库位]'", "id");
                                $where    = " coid = '" . self::$coid . "' and orderId = '{$orderId}' AND materialId = '{$material['id']}' AND positionId = '{$position['id']}' ";
                                break;
                            case 3:
                                $position = query('warehouse_position', " orderId = '$info[warehouseId]' and name = '$cell[库位]'", "id");
                                $where    = " coid = '" . self::$coid . "' and orderId = '{$orderId}' AND materialId = '{$material['id']}' AND positionId = '{$position['id']}' and batch = '$cell[批号]' ";
                                break;
                            default:
                                $where = " coid = '" . self::$coid . "' and orderId = '{$orderId}' AND materialId = '{$material['id']}' ";
                        }
                        $inventory_take_detail = query(self::tableMx, $where, 'id');
                        if (!is_numeric($cell['盘点库存'])) {
                            $text .= str_replace(['{{i}}'], [$row_list], L('inventory.importData.formatError')) . "<br>";
                        } elseif (empty($inventory_take_detail['id'])) {
                            $text .= str_replace(['{{i}}'], [$row_list], L('inventory.importData.notFind')) . "<br>";
                        } else {
                            $this->startTrans();
                            $cell['盘点库存']  = self::formattingFigure(floatval($cell['盘点库存']), 'numPrecision');
                            $num   = inventoryBalanceClass::toMainUnit($material['id'], $cell['盘点库存'], $cell['单位']);
                            $field = [
                                'num' => $num,
                            ];
                            $warn  = static::update(["table" => self::tableMx, "field" => $field, 'where' => " id = '" . $inventory_take_detail['id'] . "' "]);
                            if (in_array($warn, ['新增成功', '更新成功'])) {
                                $this->commitTrans();
                                // 更新数量
                                $x++;
                                $text .= str_replace(['{{i}}'], [$row_list], L('inventory.importData.success')) . "<br>";
                            } else {
                                $this->rollback();
                                $text .= str_replace(['{{i}}'], [$row_list], L('inventory.importData.fail')) . "<br>";
                            }
                        }
                    }
                }
            }
            $total = count($data)-1;
            $json['data'] = [
                'text'=>$text,
                'title'=>"您导入了{$total}条数据，成功{$x}条，失败".($total-$x)."条",
            ];
            $this->logText(["type" => self::page, "text" => $text]);
            $json['warn'] = 2;
        }
        return json_encode($json,320);
    }

    /**
     * 确认
     */
    public function confirmEdit(): string
    {
        $id    = $this->post('id');
        $info  = query(self::table, " coid = '" . self::$coid . "' AND id = '$id'");
        $field = [
            'state'       => '已确认',
            'confirmTime' => $this->time,
        ];
        if (!$this->power(self::page, 'confirm')) {
            $json['warn'] = L('inventory.confirmEdit.power');
        } else {
            if (empty($info['id'])) {
                $json['warn'] = L('inventory.confirmEdit.empty');
            } else {
                if ($info['state'] != '待确认') {
                    $json['warn'] = L('inventory.confirmEdit.stateError');
                } else {
                    $this->startTrans();
                    $isPass       = true; // 事务通过标志
                    $json['warn'] = update([
                        "table" => self::table,
                        "field" => $field,
                        "where" => "id = '$info[id]'",
                    ]);
                    if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                        $this->commitTrans();//提交事务
                        auditingFollow([
                            "type"   => "盘点单",
                            "typeId" => $info['id'],
                            "text"   => "【{$this->control['name']}】确认",
                        ]);
                        //添加日志
                        $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                        $text = str_replace(['{{staffName}}', '{{type}}', '{{id}}'], [$this->control['name'], $type, $id], L('inventory.confirmEdit.log'));
                        $this->logText(["type" => self::page, "text" => $text]);
                        //返回
                        $_SESSION['warn'] = $json['warn'];
                        $json['warn']     = 2;
                        $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
                    }
                }
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 生产盈亏单
     *
     * @return string
     */
    public function generateInventory(): string
    {
        $id       = $this->post('id');
        $changeId = self::getId();
        $type     = $this->post('type');
        if (static::isNull($id)) {
            $json['warn'] = L('inventory.generateInventory.error');
        } else {
            $where = " orderId = '$id' ";
            if ($type == '盘盈单') {
                $mtype       = '其他入库';
                $prefix      = 'QTRK' . date('Ymd');
                $where       .= " AND num > orderNum ";
                $subCategory = '盘盈';
                $classify    = 1;
                $state       = '已入库';
                $orderNo     = codeTemplateClass::generateCode('inStockOther', [
                    'prefix' => $prefix,
                    'table'  => 'inventory',
                    'where'  => " AND coid = '" . self::$coid . "' ",
                ], []);
            } else {
                $mtype       = '其他出库';
                $prefix      = 'QTCK' . date('Ymd');
                $where       .= " AND num < orderNum ";
                $subCategory = '盘亏';
                $classify    = 0;
                $state       = '已出库';
                $orderNo     = codeTemplateClass::generateCode('outStockOther', [
                    'prefix' => $prefix,
                    'table'  => 'inventory',
                    'where'  => " AND coid = '" . self::$coid . "' ",
                ], []);
            }
            $total = static::total([
                'table' => 'inventory',
                'where' => [
                    'sourceTable' => self::table,
                    'sourceId'    => $id,
                    'type'        => $mtype,
                ],
            ]);
            $info  = query(self::table, " id = '$id'");
            if (empty($info)) {
                $json['warn'] = L('inventory.generateInventory.empty');
            } elseif ($total > 0) {
                $json['warn'] = str_replace(['{{mtype}}', '{{type}}'], [$mtype, $type], L('inventory.generateInventory.repeat'));
            } else {
                $result = find([
                    'table' => self::tableMx,
                    'where' => $where,
                ]);
                if (static::is_null_array($result['array'])) {
                    $json['warn'] = str_replace(['{{type}}'], [$type], L('inventory.generateInventory.unable'));
                } else {
                    $optionSetting = optionSettingClass::getSetting('公共');  //选项设置
                    $batchCtrl = $optionSetting['batchCtrl'];
                    $inId = self::getId();
                    $this->startTrans();
                    static::insert([
                        'table' => 'inventory',
                        'field' => [
                            'id'          => $inId,
                            'coid'        => self::$coid,
                            'orderNo'     => $orderNo,
                            'orderDate'   => $this->date,
                            'type'        => $mtype,
                            'subCategory' => $subCategory,
                            'classify'    => $classify,
                            'sourceTable' => 'inventory_take',
                            'sourceId'    => $info['id'],
                            'warehouseId' => $info['warehouseId'],
                            'state'       => $state,
                            'stid'        => self::$stid,
                        ],
                    ]);
                    static::insert([
                        'table' => 'inventory_changes',
                        'field' => [
                            'id'          => $changeId,
                            'coid'        => self::$coid,
                            'orderNo'     => codeTemplateClass::generateCode('outStock', [
                                'prefix' => 'CKD' . date('Ymd'),
                                'table'  => 'inventory_changes',
                                'field'  => 'orderNo',
                                'where'  => " and coid = '" . self::$coid . "'",
                            ], []),
                            'type'        => $mtype,
                            'classify'    => $classify,
                            'recordDate'  => $this->date,
                            'confirmTime' => $this->date,
                            'reviewTime'  => $this->date,
                            'state'       => '已复核',
                            'stid'        => self::$stid,
                        ],
                    ]);
                    if ($type == '盘盈单') {
                        /*if($batchCtrl['option']  && $batchCtrl['auto']) {
                            $batch = inStockClass::getBatchNo('其他入库', '');
                        }else{
                            $batch = "";
                        }*/
                        foreach ((array)$result['array'] as $value) {
                            $positionId = $value['positionId'] ?: inventoryBalanceClass::matchLocation($info['warehouseId']);
                            $price = inventoryBalanceClass::unitPrice($value['materialId']);
                            $num   = abs($value['num'] - $value['orderNum']);
                            static::insert([
                                'table' => 'inventory_detail',
                                'field' => $inventory_detail_fieldMx = [
                                    'id'            => self::getId(),
                                    'coid'          => self::$coid,
                                    'orderId'       => $inId,
                                    'materialId'    => $value['materialId'],
                                    'orderNum'      => $num,
                                    'num'           => $num,
                                    'price'         => $price,
                                    'money'         => round($num * $price, 2),
                                    'unit'          => $value['unit'],
                                    'sourceTable'   => 'inventory_take_detail',
                                    'sourceId'      => $value['id'],
                                    'warehouseId'   => $info['warehouseId'],
                                    'positionId'    => $positionId,
                                    'batch'         => $value['batch'],
                                ],
                            ]);
                            static::insert(array(
                                'table' => 'inventory_changes_detail',
                                'field' => $fieldChangeMx = [
                                    'id'            => self::getId(),
                                    'coid'          => self::$coid,
                                    'orderId'       => $changeId,
                                    'materialId'    => $value['materialId'],
                                    'orderNum'      => $num,
                                    'num'           => $num,
                                    'unit'          => $value['unit'],
                                    'price'         => $price,
                                    'sourceTable'   => 'inventory_detail',
                                    'sourceId'      => $inventory_detail_fieldMx['id'],
                                    'sourceNo'      => $orderNo,
                                    'warehouseId'   => $info['warehouseId'],
                                    'positionId'    => $positionId,
                                    'batch'         => $value['batch'],
                                ]
                            ));
                            $recordId = self::getNo();
                            static::insert([
                                'table' => self::tableRecord,
                                'field' => [
                                    'id'            => $recordId,
                                    'coid'          => self::$coid,
                                    'warehouseId'   => $fieldChangeMx['warehouseId'],
                                    'positionId'    => $fieldChangeMx['positionId'],
                                    'materialId'    => $fieldChangeMx['materialId'],
                                    'batch'         => $fieldChangeMx['batch'],
                                    'num'           => $fieldChangeMx['num'],
                                    'inventoryId'   => $inventory_detail_fieldMx['orderId'],
                                    'inventoryMxId' => $inventory_detail_fieldMx['id'],
                                    'changesId'     => $fieldChangeMx['id'],
                                ],
                            ]);
                            if (!empty($fieldChangeMx['positionId'])) inventoryBalanceClass::recordStockToLocation($recordId, ['positionId' => $fieldChangeMx['positionId']]);
                        }
                    } else {
                        foreach ((array)$result['array'] as $value) {
                            $price = inventoryBalanceClass::unitPrice($value['materialId']);
                            $num   = abs($value['num'] - $value['orderNum']);
                            //判断库存
                            $mainUnitNum = inventoryBalanceClass::toMainUnit($value['materialId'], $num, $value['unit']);
                            /*if (inventoryBalanceClass::inventoryNum($value['materialId'], $info['warehouseId']) - $mainUnitNum < 0) {
                                $json['warn'] = L('inventory.generateInventory.overrun');
                                goto resp;
                            }*/
                            if ($info['mold'] == 3) {
                                static::insert([
                                    'table' => 'inventory_detail',
                                    'field' => $inventory_detail_fieldMx = [
                                        'id'          => self::getId(),
                                        'coid'        => self::$coid,
                                        'orderId'     => $inId,
                                        'materialId'  => $value['materialId'],
                                        'orderNum'    => $mainUnitNum,
                                        'num'         => $mainUnitNum,
                                        'price'       => $price,
                                        'money'       => round($mainUnitNum * $price, 2),
                                        'unit'        => $value['unit'],
                                        'sourceTable' => 'inventory_take_detail',
                                        'sourceId'    => $value['id'],
                                        'warehouseId' => $info['warehouseId'],
                                        'positionId'    => $value['positionId'],
                                        'batch'         => $value['batch'],
                                    ],
                                ]);
                                static::insert(array(
                                    'table' => 'inventory_changes_detail',
                                    'field' => $fieldChangeMx = [
                                        'id'          => self::getId(),
                                        'coid'        => self::$coid,
                                        'orderId'     => $changeId,
                                        'materialId'  => $value['materialId'],
                                        'orderNum'    => $mainUnitNum,
                                        'num'         => $mainUnitNum,
                                        'unit'        => $value['unit'],
                                        'price'       => $price,
                                        'sourceTable' => 'inventory_detail',
                                        'sourceId'    => $inventory_detail_fieldMx['id'],
                                        'sourceNo'    => $orderNo,
                                        'warehouseId' => $info['warehouseId'],
                                        'positionId'    => $value['positionId'],
                                        'batch'         => $value['batch'],
                                    ]
                                ));
                                static::insert([
                                    'table' => self::tableRecord,
                                    'field' => [
                                        'id'            => self::getNo(),
                                        'coid'          => self::$coid,
                                        'warehouseId'   => $fieldChangeMx['warehouseId'],
                                        'positionId'    => $fieldChangeMx['positionId'],
                                        'materialId'    => $fieldChangeMx['materialId'],
                                        'batch'         => $fieldChangeMx['batch'],
                                        'num'           => -1 * $fieldChangeMx['num'],
                                        'inventoryId'   => $inventory_detail_fieldMx['orderId'],
                                        'inventoryMxId' => $inventory_detail_fieldMx['id'],
                                        'changesId'     => $fieldChangeMx['id'],
                                    ],
                                ]);
                                if (!empty($fieldChangeMx['positionId'])) {
                                    inventoryBalanceClass::recordStockToLocation(
                                        '',
                                        [
                                            'materialId'  => $fieldChangeMx['materialId'],
                                            'warehouseId' => $fieldChangeMx['warehouseId'],
                                            'positionId'  => $fieldChangeMx['positionId'],
                                            'batch'       => $fieldChangeMx['batch']
                                        ]
                                    );
                                }
                            }else {
                                //查询从早到晚的所有仓位和批次剩余的库存，依次出库
                                if ($info['mold'] == 2) {
                                    $fieldArr = self::resolveField([
                                        'field' => '`id`, `coid`, `positionId`,`batch`, `materialId`, SUM(num) as num, `time`',
                                        'group' => 'batch',
                                    ]);
                                    //查询结果
                                    $where  = " coid = '" . self::$coid . "' and materialId = '$value[materialId]' and warehouseId = '" . $info['warehouseId'] . "' and positionId = '" . $value['positionId'] . "' ";
                                    $where  .= $fieldArr['group'];

                                }else {
                                    $fieldArr = self::resolveField([
                                        'field' => '`id`, `coid`, `positionId`,`batch`, `materialId`, SUM(num) as num, `time`',
                                        'group' => 'positionId,batch',
                                    ]);
                                    //查询结果
                                    $where  = " coid = '" . self::$coid . "' and materialId = '$value[materialId]' and warehouseId = '" . $info['warehouseId'] . "' ";
                                    $where  .= $fieldArr['group'];
                                }
                                $result = find(array('table' => 'inventory_record', 'field' => $fieldArr['field'], 'where' => $where . " having sum(num)>0 order by time "));
                                foreach ((array)$result['array'] as $array) {
                                    if ($mainUnitNum > 0) {
                                        if ($mainUnitNum > $array['num']) {
                                            $now = $array['num'];
                                        } else {
                                            $now = $mainUnitNum;
                                        }
                                        $mainUnitNum -= $now;
                                        static::insert([
                                            'table' => 'inventory_detail',
                                            'field' => $inventory_detail_fieldMx = [
                                                'id'          => self::getId(),
                                                'coid'        => self::$coid,
                                                'orderId'     => $inId,
                                                'materialId'  => $value['materialId'],
                                                'orderNum'    => $now,
                                                'num'         => $now,
                                                'price'       => $price,
                                                'money'       => round($now * $price, 2),
                                                'unit'        => $value['unit'],
                                                'sourceTable' => 'inventory_take_detail',
                                                'sourceId'    => $value['id'],
                                                'warehouseId' => $info['warehouseId'],
                                                'positionId'  => $array['positionId'],
                                                'batch'       => $array['batch'],
                                            ],
                                        ]);
                                        static::insert(array(
                                            'table' => 'inventory_changes_detail',
                                            'field' => $fieldChangeMx = [
                                                'id'          => self::getId(),
                                                'coid'        => self::$coid,
                                                'orderId'     => $changeId,
                                                'materialId'  => $value['materialId'],
                                                'orderNum'    => $now,
                                                'batch'       => $array['batch'],
                                                'num'         => $now,
                                                'unit'        => $value['unit'],
                                                'price'       => $price,
                                                'sourceTable' => 'inventory_detail',
                                                'sourceId'    => $inventory_detail_fieldMx['id'],
                                                'sourceNo'    => $orderNo,
                                                'warehouseId' => $info['warehouseId'],
                                                'positionId'  => $array['positionId'],
                                            ]
                                        ));
                                        static::insert([
                                            'table' => self::tableRecord,
                                            'field' => [
                                                'id'            => self::getNo(),
                                                'coid'          => self::$coid,
                                                'warehouseId'   => $fieldChangeMx['warehouseId'],
                                                'positionId'    => $fieldChangeMx['positionId'],
                                                'materialId'    => $fieldChangeMx['materialId'],
                                                'batch'         => $fieldChangeMx['batch'],
                                                'num'           => -1 * $fieldChangeMx['num'],
                                                'inventoryId'   => $inventory_detail_fieldMx['orderId'],
                                                'inventoryMxId' => $inventory_detail_fieldMx['id'],
                                                'changesId'     => $fieldChangeMx['id'],
                                            ],
                                        ]);
                                        if (!empty($fieldChangeMx['positionId'])) {
                                            inventoryBalanceClass::recordStockToLocation(
                                                '',
                                                [
                                                    'materialId'  => $fieldChangeMx['materialId'],
                                                    'warehouseId' => $fieldChangeMx['warehouseId'],
                                                    'positionId'  => $fieldChangeMx['positionId'],
                                                    'batch'       => $fieldChangeMx['batch']
                                                ]
                                            );
                                        }
                                    }
                                }
                            }
                        }
                    }
                    $this->commitTrans();//提交事务
                    $json['warn']     = 2;
                    $_SESSION['warn'] = str_replace(['{{type}}'], [$type], L('inventory.generateInventory.success'));
                }
            }
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 取消
     */
    public function cancelEdit(): string
    {
        $id    = $this->post('id');
        $info  = query(self::table, " coid = '" . self::$coid . "' AND id = '$id'");
        $field = [
            'state'       => '草稿',
            'confirmTime' => '',
        ];
        if (!$this->power(self::page, 'cancel')) {
            $json['warn'] = L('inventory.cancelEdit.power');
        } elseif (static::total(array('table' => 'inventory', "where" => "sourceId = '$info[id]' and coid = '" . self::$coid . "' and state in ('部分入库','已入库','部分出库','已出库')")) > 0) {
            $json['warn'] = '此盘点单已有盘盈盘亏出入库数据，不能撤回';
        } else {
            if (empty($info['id'])) {
                $json['warn'] = L('inventory.cancelEdit.empty');
            } else {
                $json['warn'] = update([
                    "table" => self::table,
                    "field" => $field,
                    "where" => "id = '$info[id]'",
                ]);
                if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                    auditingFollow(array(
                        "type"   => "盘点单",
                        "typeId" => $info['id'],
                        "text"   => "【{$this->control['name']}】取消",
                    ));
                    //添加日志
                    $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                    $text = str_replace(['{{staffName}}', '{{type}}', '{{id}}'], [$this->control['name'], $type, $id], L('inventory.cancelEdit.log'));
                    $this->logText(["type" => self::page, "text" => $text]);
                    //返回
                    $_SESSION['warn'] = $json['warn'];
                    $json['warn']     = 2;
                    $json['href']     = root . "control/adIndex.html?cla=" . $this->get(
                            'cla'
                        ) . "&fun=detail&id=" . $info['id'];
                }
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 提交
     */
    public function commitEdit(): string
    {
        $id    = $this->post('id');
        $info  = query(self::table, " coid = '" . self::$coid . "' AND id = '$id'");
        $field = [
            'state'      => '待确认',
            'commitTime' => $this->time,
        ];
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = L('inventory.commitEdit.power');
        } else {
            if (empty($info['id'])) {
                $json['warn'] = L('inventory.commitEdit.empty');
            } else {
                if ($info['state'] != '草稿') {
                    $json['warn'] = L('inventory.commitEdit.stateError');
                } else {
                    $json['warn'] = update(array(
                        "table" => self::table,
                        "field" => $field,
                        "where" => "id = '$info[id]'",
                    ));
                    if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                        auditingFollow([
                            "type"   => "盘点单",
                            "typeId" => $info['id'],
                            "text"   => "【{$this->control['name']}】提交",
                        ]);
                        //添加日志
                        $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                        $text = str_replace(['{{staffName}}', '{{type}}', '{{id}}'], [$this->control['name'], $type, $id], L('inventory.commitEdit.log'));
                        $this->logText(["type" => self::page, "text" => $text]);
                        //返回
                        $_SESSION['warn'] = $json['warn'];
                        $json['warn']     = 2;
                        $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
                    }
                }
            }
        }
        resp:
        return json_encode($json, 320);
    }

    // 操作中转
    public function operate(): string
    {
        $act   = $this->post('act') ?? '';
        $pwd   = $word = false; // 需要密码
        $power = '';
        switch ($act) {
            case 'confirm':
                $act      = 'confirm';
                $msg      = L('inventory.operate.confirm');
                $title    = L('inventory.operate.confirmTitle');
                $function = 'confirmEdit';
                $form     = self::page . 'OperateForm, detailForm';
                $word     = true;
                break;
            case 'commit':
                $act      = 'edit';
                $msg      = L('inventory.operate.commit');
                $title    = L('inventory.operate.commitTitle');
                $function = 'commitEdit';
                $form     = self::page . 'OperateForm, detailForm';

                $word = true;
                break;
            case 'cancel':
                $act      = 'cancel';
                $msg      = L('inventory.operate.cancel');
                $title    = L('inventory.operate.cancelTitle');
                $function = 'cancelEdit';
                $form     = self::page . 'OperateForm, detailForm';

                $word = true;
                break;
            default:
                $act      = 'del';
                $msg      = L('inventory.operate.del');
                $title    = self::page . 'Delete';
                $function = 'delete';
                $form     = self::page . 'OperateForm, listForm, quoForm';

                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = str_replace(['{{msg}}'], [$msg], L('inventory.operate.warn'));
            $json             = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title'    => $title,
                'function' => $function,
                'form'     => $form,
                'power'    => $power,
                'pwd'      => $pwd,
                'word'     => $word,
            ]);
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 删除
     *
     * @return bool|string
     */
    public function delete(): string|false
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = L('inventory.delete.power');
        } else {
            if (empty($array)) {
                $json['warn'] = L('inventory.delete.noChoice');
            } else {
                $text  = "";
                $x     = 0;
                $array = is_array($array) ? $array : [$array];
                foreach ($array as $id) {
                    $info = query(self::table, " coid = '" . self::$coid . "' AND id = '$id' ");
                    if ($info['state'] == '已确认') {
                        $warn = L('inventory.delete.fail');
                    } else {
                        //最后删除基本参数
                        delete(array("table" => self::table, "where" => " id = '$id' "));
                        delete(array("table" => self::tableMx, "where" => " orderId = '$id' "));
                        delete(array("table" => 'auditing_follow', "where" => " typeId = '$id' "));
                        //返回
                        $warn = L('inventory.delete.success');
                        $x++;
                    }
                    $text .= str_replace(['{{id}}'], [$info['id']], L('inventory.delete.text')) . $warn . "。<br>";
                }
                //添加日志
                $text = str_replace(['{{staffName}}'], [$this->control['name']], L('inventory.delete.log')) . "<br>" . $text;
                $this->logText(array("type" => self::page, "text" => $text));
                $_SESSION['warn'] = str_replace(['{{x}}'], [$x], L('inventory.delete.warn'));
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
            }
        }
        return json_encode($json, 320);
    }

    /**
     * 导出
     */
    public function exportData()
    {
        $templateId = $this->get('templateId');
//        $checkedId = $this->get('checkedId')?explode(',',$this->get('checkedId')):[];
        if (!$this->power(self::page, 'export')) {
            $_SESSION['warn'] = L('inventory.delete.power');
        } else {
            $info = query(self::table, " id = '{$this->get('id')}' ");
            if (empty($info['id'])) {
                $_SESSION['warn'] = L('inventory.delete.none');
            } else {
                $data = [];
                /***********标题**********/
                $title =[];
                $tempFieldAll = importTemplateClass::templateField(self::page, 'exportFieldInit', id:$templateId);
                foreach ($tempFieldAll as $array) {
                    if ($array['display']){
                        $title[] = $array['aliasName'];
                    }
                }
                //判断是否选中导出
                $result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by time"))['array'];
                //导出数据生成
                foreach ($result as $array){
                    $column = [];
                    $material    = query('material', " id = '$array[materialId]'");
                    $position    = query('warehouse_position', " id = '$array[positionId]'", "name");
                    foreach ($tempFieldAll as $templateField){
                        if ($templateField['display']){
                            $column[] = match ($templateField['columnName']){
                                '物料编码'=>$material['code'],
                                '物料名称'=>$material['name'],
                                '规格型号'=>$material['model'],
                                '单位'=>$material['unit'],
                                '库位'=>$position['name'],
                                '批号'=>$array['batch'],
                                '系统库存'=>self::lostZero($array['orderNum'], 'numPrecision'),
                                '盘点库存'=>self::lostZero($array['num'], 'numPrecision'),
                                '差异'=>self::formattingFigure($array['num'] - $array['orderNum'], 'numPrecision'),
                                default=>'',
                            };
                        }
                    }
                    $data[] = $column;
                }
                $text = str_replace(['{{staffName}}'], [$this->control['name']], L('inventory.exportData.log'));
                $this->logText(["type" => self::page, "text" => $text]);
                $this->excelOut($title, $data, L('inventory.exportData.fileName') . ".xlsx");
                exit(0);
            }
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }


    /**
     * 导入模板字段初始化
     * @return array[]
     */
    public function importFieldInit($classify=''): array
    {
        return match ($classify) {
            default=>  [
                [
                    'columnName'=>'物料编码',
                    'aliasName'=>'物料编码',
                    'isMust'=>true,
                ],
                [
                    'columnName'=>'物料名称',
                    'aliasName'=>'物料名称',
                ],
                [
                    'columnName'=>'规格型号',
                    'aliasName'=>'规格型号',
                ],
                [
                    'columnName'=>'单位',
                    'aliasName'=>'单位',
                    'isMust'=>false,
                ],
                [
                    'columnName'=>'库位',
                    'aliasName'=>'库位',
                    'isMust'=>true,
                ],
                [
                    'columnName'=>'批号',
                    'aliasName'=>'批号',
                    'isMust'=>true,
                ],
                [
                    'columnName'=>'系统库存',
                    'aliasName'=>'系统库存',
                ],
                [
                    'columnName'=>'盘点库存',
                    'aliasName'=>'盘点库存',
                    'isMust'=>true,
                ],
            ]
        };
    }

    /**
     * 导出模板字段初始化
     * @return array[]
     */
    public function exportFieldInit($classify=''): array
    {
        return match ($classify) {

            default=>  [
                [
                    'columnName'=>'物料编码',
                    'aliasName'=>'物料编码',
                ],
                [
                    'columnName'=>'物料名称',
                    'aliasName'=>'物料名称',
                ],
                [
                    'columnName'=>'规格型号',
                    'aliasName'=>'规格型号',
                ],
                [
                    'columnName'=>'单位',
                    'aliasName'=>'单位',
                ],
                [
                    'columnName'=>'库位',
                    'aliasName'=>'库位',
                ],
                [
                    'columnName'=>'批号',
                    'aliasName'=>'批号',
                ],
                [
                    'columnName'=>'系统库存',
                    'aliasName'=>'系统库存',
                ],
                [
                    'columnName'=>'盘点库存',
                    'aliasName'=>'盘点库存',
                ],
                [
                    'columnName'=>'差异',
                    'aliasName'=>'差异',
                ],
            ]
        };
    }
}
